﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Workflow.ComponentModel;
using OpenComposite.Workflow;
using System.ComponentModel.Design;

namespace OpenComposite.Workflow.Extenders
{
	[ProvideProperty("OutputVarName", typeof(Activity))]
	public class OutputVariableNameExtenderProvider : IExtenderProvider
	{
		#region IExtenderProvider Members

		public bool CanExtend(object extendee)
		{
			DataAggregatorActivity dataAgg = extendee as DataAggregatorActivity;
			if ( dataAgg != null && dataAgg.LogicalActivityId > 0 ) return true;

			LogicalAsyncEndActivity logAsyncEndAct = extendee as LogicalAsyncEndActivity;
			if ( logAsyncEndAct != null && !string.IsNullOrEmpty(logAsyncEndAct.StartActivityName) ) return true;

			LogicalCapabilityActivity logAct = extendee as LogicalCapabilityActivity;
			if ( logAct != null ) return logAct.HasOutputObject;

			LogicalMethodCallActivity lmca = extendee as LogicalMethodCallActivity;
			if ( lmca != null && lmca.LogicalActivityId > 0 ) return lmca.HasOutputObject;

			LogicalInputActivity lia = extendee as LogicalInputActivity;
			if ( lia != null && lia.LogicalActivityId > 0 ) return lia.HasOutputObject;

			RuleEvaluatorActivity rea = extendee as RuleEvaluatorActivity;
			if ( rea != null && rea.LogicalActivityId > 0 ) return true;

			return false;
		}

		#endregion

		public static void RegisterExtender(
			IExtenderListService extenderListService,
			IExtenderProviderService extenderProviderService)
		{
			if ( extenderListService != null ) {
				bool foundExtender = false;
				foreach ( IExtenderProvider extenderProvider in extenderListService.GetExtenderProviders() ) {
					if ( extenderProvider.GetType() == typeof(OutputVariableNameExtenderProvider) ) {
						foundExtender = true;
						break;
					}
				}

				if ( !foundExtender ) {
					if ( extenderProviderService != null ) {
						extenderProviderService.AddExtenderProvider(new OutputVariableNameExtenderProvider());
					}
				}
			}
		}

		public static DependencyProperty OutputVarNameProperty =
			DependencyProperty.RegisterAttached(
				"OutputVarName", typeof(string), typeof(OutputVariableNameExtenderProvider));

		public static object GetOutputVarName(object dependencyObject)
		{
			return ( (DependencyObject)dependencyObject ).GetValue(OutputVarNameProperty);
		}
		public static void SetOutputVarName(object dependencyObject, object value)
		{
			( (DependencyObject)dependencyObject ).SetValue(OutputVarNameProperty, value);
		}

		public string GetOutputVarName(Activity activity)
		{
			string value = null;

			if ( activity is LogicalCapabilityActivity ||
				 activity is DataAggregatorActivity ||
				 activity is LogicalMethodCallActivity ||
				 activity is LogicalInputActivity ||
				 activity is RuleEvaluatorActivity ) {
				value = (string)activity.GetValue(OutputVariableNameExtenderProvider.OutputVarNameProperty);
			}
			return value;
		}
		public void SetOutputVarName(Activity activity, string value)
		{
			if ( activity is LogicalCapabilityActivity ||
				 activity is DataAggregatorActivity ||
				 activity is LogicalMethodCallActivity ||
				 activity is LogicalInputActivity ||
				 activity is RuleEvaluatorActivity ) {
				activity.SetValue(OutputVariableNameExtenderProvider.OutputVarNameProperty, value);
			}
		}
	}
}
